home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 1
-
-
- TABLE OF CONTENTS
-
-
- INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . 2
-
- CONVENTIONS, OPENING MACROS AND CLOSING MACROS . . . . . . . 3
- LISTING CONTROL . . . . . . . . . . . . . . . . . . . . 3
- OUT_UNNECESSARY_LONG_COMMENTS - Closing summary macro . 3
- BLANK MACRO ARGUMENTS . . . . . . . . . . . . . . . . . 3
- CONVENTIONS IN THIS DOCUMENTATION . . . . . . . . . . . 4
-
- A STRATEGY TO MINIMIZE THE NUMBER OF LONG JUMPS . . . . . . 5
-
- JUMPS TO EXPLICIT LABELS . . . . . . . . . . . . . . . . . . 6
- GENERAL . . . . . . . . . . . . . . . . . . . . . . . . 6
- LJMP TARGET_LABEL, LONG - Unconditional jump to
- TARGET_LABEL. . . . . . . . . . . . . . . . . . . 6
- LCJMP CONDITION-1, TARGET_LABEL, LONG - Conditional
- jump to TARGET_LABEL. . . . . . . . . . . . . . . 6
- LJCXZ TARGET_LABEL, LONG - Jump to TARGET_LABEL if
- register CX is zero. . . . . . . . . . . . . . . . 6
- LLOOP CONDITION-3, TARGET_LABEL, LONG - Conditional and
- unconditional loops. . . . . . . . . . . . . . . . 6
-
- STRUCTURED MACROS . . . . . . . . . . . . . . . . . . . . . 7
- GENERAL . . . . . . . . . . . . . . . . . . . . . . . . 7
- Jump to the beginning or the end of an "enclosing
- block" . . . . . . . . . . . . . . . . . . . . . . 8
- BEGIN and END . . . . . . . . . . . . . . . . . . . . . 9
- IF and IF - ELSE with one condition . . . . . . . . . . 9
- IF and IF - ELSE with multiple AND conditions . . . . . 10
- Repetition for a count . . . . . . . . . . . . . . . . 11
- WHILE . . . . . . . . . . . . . . . . . . . . . . . . . 12
- REPEAT UNTIL . . . . . . . . . . . . . . . . . . . . . 12
- REPEAT FOREVER . . . . . . . . . . . . . . . . . . . . 12
-
- OTHER MACROS . . . . . . . . . . . . . . . . . . . . . . . . 13
- Multiple PUSH and POP . . . . . . . . . . . . . . . . . 13
- Show the state of the Zero Flag in AL . . . . . . . . . 13
- NOTZ - Toggle the Zero Flag . . . . . . . . . . . . . . 13
- Call procedures which use a string whose OFFSET is in
- either BX or DX . . . . . . . . . . . . . . . . . 13
- Call a procedure which uses a File Control Block . . . 14
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 2
-
-
-
- I. INTRODUCTION
-
- I based this collection of macros for MicroSoft MASM on
- MACROS.MLB in the public domain file HERSHMAC.ARC, which Mark
- Hersey of Hersey Micro Consulting, Inc. wrote. I made enough
- changes so that I can not claim that his work created any
- problems you might find with it.
-
- HERSHMAC.ARC also includes the following files which define
- symbolic constants:
- CHARS.MLB contains constant declarations for ASCII
- characters.
- I8086.MLB contains constant declarations which are for
- use with an 8086 assembler.
- MSDOS.MLB contains constant declarations which are for
- use with Seattle Computer Products MS-DOS operating system.
- They seem useable for Microsoft's PC-DOS also.
- I have tried to be sure that MACROS.MLB and these three files do
- not depend on one another. I have included them in this ARChive.
-
- Michael Abrash's article "Conditional-jump Macros" in the
- February, 1987 issue of "PC Tech Journal" inspired the macros
- which begin with the letter L and give various forms of jump and
- loop instructions.
-
- Since I am placing these macros in the public domain, I am
- not responsible for any bad things which they might do.
-
- Lew Paper
- 10:53 am on 3/1/87
-
-
-
-
-
- Documentation for MACROS.MLB Page 3
-
-
-
- II. CONVENTIONS, OPENING MACROS AND CLOSING MACROS
-
- A. LISTING CONTROL
-
- MASM allows three kinds of listing for macro expansions.
- .LALL lists code and ";" comments; .XALL lists code only; .SALL
- surpresses all listing. The default is .XALL.
-
- MACROS.MLB uses the macro variable MACRO_EXPANSION_CONTROL
- to specify which level you want. If it is not defined, it
- assumes .XALL, which is consistent with the MASM default. Its
- definitions are:
- 0 for .XALL (list code only)
- 1 for .SALL (surpress all listing)
- 2 for .LALL (list code and comments).
- Any other value also gives .XALL.
-
- The macro SET_MACRO_EXPANSION actually sets MASM's listing
- control according to to the value in MACRO_EXPANSION_CONTROL.
-
- As discussed below, a long jump to a forward label which
- could be short will generate a comment. MACROS.MLB needs
- something like MACRO_EXPANSION_CONTROL to reset itself
- afterwards.
-
- B. OUT_UNNECESSARY_LONG_COMMENTS - Closing summary macro
-
- Use the macro OUT_UNNECESSARY_LONG_COMMENTS, which has no
- arguments, at the end of any file which uses any of the macros
- described in Section III, JUMPS TO EXPLICIT LABELS or Section IV,
- STRCTURED MACROS with a LONG argument. It will add a comment if
- there are any unnecessary long forward jumps and also print a
- message to that effect on the screen. It does nothing if there
- are none.
-
- Strictly speaking, you only need to use
- OUT_UNNECESSARY_LONG_COMMENTS if you have a forward long jump.
- Rather than worry about whether a structured macro is forward or
- backward, it is easier to use it in any case where it might come
- into play.
-
- C. BLANK MACRO ARGUMENTS
-
- Indicate that all arguments of a macro are blank by not
- entering a macro list. Indicate that the last argument of a
- macro is blank by ending the argument list with the last
- non-blank argument. Indicate that the first argument of a macro
- is blank by starting the macro list with a comma. Indicate that
- an internal argument of a macro is blank by entering just a comma
- following the preceding comma.
-
-
-
-
-
- Documentation for MACROS.MLB Page 4
-
-
- CONVENTIONS, OPENING MACROS AND CLOSING MACROS (Continued)
-
- D. CONVENTIONS IN THIS DOCUMENTATION
-
- CONDITION-1 is a completion to any conditional jump J
- instruction except JCXZ. Its legal values are:
- A, AE, B, BE, C, E, G, GE, L, LE, NA, NAE, NB, NBE, NC,
- NE, NG, NGE, NL, NLE, NO, NP, NS, NZ, O, P, PE, PO, S, Z.
-
- CONDITION-2 is a completion to any condition jump J
- instruction which tests flags affected by an OR instruction
- except JCXZ. The values for which it gives a choice are:
- BE, E, G, GE, L, LE, NA, NE, NG, NGE, NL, NLE, NP, NS,
- NZ, P, PE, PO, S, Z.
- It is always true, so probably not useful, for:
- A, AE, NB, NBE, NC, NO.
- It is always false, so probably not useful, for:
- B, C, O, NAE.
-
- CONDITION-3 is a completion to any LOOP instruction. Its
- legal values are:
- blank, E, NE, NZ, Z.
-
- VAR1, CONDITION, VAR2 has two meanings. If VAR2 is blank,
- it means, "AND VAR1, VAR1", then jump on CONDITION-2. Since the
- 8086 does not allow "AND mem, mem", this option only works if
- VAR1 is a register. If VAR2 is not blank, it means,
- "CMP VAR1, VAR2", then jump on CONDITION-1. Since the 8086 does
- not allow "CMP mem1, mem2", this option requires that either VAR1
- or VAR2 be either a register or an immediate variable. Most of
- the macros have a form which jumps on a condition which is
- already set. In those cases, you are free to set it by any
- operation you want.
-
- LONG forces MASM to compile a long forward jump if it is not
- blank. It is always the last argument. Anything in this
- position will do, but the word "long" could clarify your meaning.
- Incidentally, MACROS.MLB ignores LONG for a backward jump.
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 5
-
-
- III. A STRATEGY TO MINIMIZE THE NUMBER OF LONG JUMPS
-
- MASM can determine whether a backward jump is long or short
- on pass 1, but it can't do the same thing for forward jumps. The
- LONG argument is the way the macros below respond to this
- problem.
-
- One general strategy which you coud follow to assure
- yourself that there are no unnecessary long jumps is:
-
- Compile with no LONG arguments.
-
- If there are any "Relative jump out of range"
- error messages, add a LONG argument to those macros and
- compile again.
-
- Repeat the last step until there are no "Relative
- jump out of range" error messages.
-
- Since each LONG adds some bytes, it is possible that adding
- a LONG argument will spread out another forward jump so it must
- be long. You can cook up some very intertwined examples which
- would take many cycles to clear up, but usually there shouldn't
- be too many recyclings.
-
- If you are sure that a forward jump will exceed 127 bytes,
- you could use a LONG argument immediately. If you are wrong, you
- will get a comment which tells you that that particular jump
- doesn't need to be long. If this happens, I suggest that you use
- the pure general strategy which I outlined above.
-
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 6
-
-
- IV. JUMPS TO EXPLICIT LABELS
-
- A. GENERAL
-
- MASM can determine whether a backward jump is long or short
- on pass 1. It can't do the same thing for a forward jump, but it
- can tell on pass 2 if a long forward jump could have been short.
- These macros take advantage of those abilities.
-
- Each of them jump or loop to the argument target_label. For
- backward jumps, each of them either issues a short jump or else
- one or more instructions which give the same conditional effect
- if any and issue a long jump.
-
- For forward jumps, they all use the variable LONG, which I
- described in Section II-D above. MASM will flag short forward
- jumps which should have been long as an error 53, "Relative jump
- out of range." Each of these macros write a comment, "******
- This jump doesn't need to be LONG ******" for a long forward jump
- which could have been short.
-
- See Section III above for a strategy which minimizes the
- number of long jumps.
-
- B. LJMP TARGET_LABEL, LONG - Unconditional jump to TARGET_LABEL.
-
- C. LCJMP CONDITION-1, TARGET_LABEL, LONG - Conditional jump to
- TARGET_LABEL.
-
- CONDITION-1 is the conditional part of any J? operation
- except JCXZ. See Section II-D above for a complete list.
-
- D. LJCXZ TARGET_LABEL, LONG - Jump to TARGET_LABEL if register
- CX is zero.
-
- E. LLOOP CONDITION-3, TARGET_LABEL, LONG - Conditional and
- unconditional loops.
-
- Use "LLOOP ,TARGET_LABEL, LONG" for an unconditional loop.
- See Section II-C for a discussion of blank macro arguments.
- Otherwise, E, NE, NZ, Z are legal values for CONDITION-3.
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 7
-
-
-
- V. STRUCTURED MACROS
-
- A. GENERAL
-
- Structured macros are combinations of macros which produce
- the effects of structured programming. They generate their own
- labels, which have the form L?n, where n is a number which is
- more or less sequential. They can be nested almost indefinitely.
-
- They use all of the long and short features of jumps to
- explicit labels discussed in Section III-A above. If a component
- macro includes a forward jump, its arguments will terminate with
- LONG. See Section III above for a strategy which minimizes the
- number of long jumps.
-
- See Section II-D for descriptions of arguments not
- explicitly described with the structured macro.
-
- The list of structured macros below is probably not
- complete. You can use the source code to build other
- combinations to fit your particular needs.
-
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 8
-
-
- STRUCTURED MACROS (Continued)
-
- B. Jump to the beginning or the end of an "enclosing block"
-
- I will define the term "enclosing block" to mean a pair of
- macros which establish internal labels at the start of the first
- one and after the second one. Several of the macro combinations
- discussed below form enclosing blocks. The following macros will
- jump to the beginning or past the end of any of them:
-
- XNEXT LONG ; Unconditionally jump to the
- ; beginning of the block
-
- XCNEXT VAR1, CONDITION, VAR2, LONG
- ; Set condition then conditionally
- ; jump to the beginning of the
- ; block
-
- XCNEXTC CONDITION-1, LONG
- ; Jump to the beginning of the
- ; block based on the condition when
- ; you invoke the macro
-
- XEXIT LONG ; Unconditionally jump to beyond
- ; the end of the block
-
- XCEXIT VAR1, CONDITION, VAR2, LONG
- ; Set condition then conditionally
- ; jump to beyond the end of the
- ; block
-
- XCEXITC CONDITION-1 LONG
- ; Jump to beyond the end of the
- ; block based on the condition when
- ; you invoke the macro
-
- You can use these macros outside of an enclosing block. The
- NEXT macros will look for the internal label with the next
- sequential number, and the EXIT macros will look for the internal
- label with the current sequential number plus 2. There are
- enough possibilities so that their effect is somewhat
- unpredicable. I suggest a jump to an explicit label instead.
-
- If these macros are used inside of an enclosing block,
- XEXIT, XCEXIT and XCEXITC include forward jumps.
-
- Each section will say whether its macros form an enclosing
- block.
-
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 9
-
-
- STRUCTURED MACROS (Continued)
-
- C. BEGIN and END
-
- XBEGIN
- body
- XEND
-
- BEGIN and END form an enclosing block with no other effects.
-
- D. IF and IF - ELSE with one condition
-
- XIF VAR1, CONDITION, VAR2, LONG
- body
- XENDIF
-
- If you want to set CONDITION-1 before you invoke XIF,
- replace the XIF line with
- XIFC CONDITION-1, LONG
-
- Each of these forms allows an optional ELSE clause. For
- example, the first form becomes:
-
- XIF VAR1, CONDITION, VAR2, LONG
- body-1
- XELSE LONG
- body-2
- XENDIF
-
- XIF, XIFC and XELSE each include forward jumps.
-
- XIF and XENDIF form an enclosing block as long as there is
- no XELSE between them. If there is an XELSE between them, they
- do not form and enclosing block. For this reason, it is probably
- safer to use XBEGIN and XEND around body-1 and/or body-2 if you
- want any form of XNEXT or XEXIT.
-
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 10
-
-
- STRUCTURED MACROS (Continued)
-
- E. IF and IF - ELSE with multiple AND conditions
-
- XIF VAR1, CONDITION, VAR2, LONG
- XANDIF VAR1, CONDITION, VAR2, LONG
- ; The two invocations should have
- ; at least one of VAR1, CONDITION
- ; and VAR2 different to be useful.
- body
- XENDIF
-
- You must first use exactly one XIF. You can then use more
- than one XANDIF.
-
- You can use both XIFC and XELSE as above in this form. In
- addition, you can set CONDITION-1 for an XANDIF and replace it
- with
- XANDIFC CONDITION-1, LONG
-
- XANDIF and XANDIFC each include forward jumps.
-
- XIF or XIFC and XENDIF form an enclosing block as long as
- there is no XELSE between them. If there is an XELSE between
- them, they do not form and enclosing block. For this reason, it
- is probably safer to use XBEGIN and XEND around body-1 and/or
- body-2 if you want any form of XNEXT or XEXIT.
-
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 11
-
-
- STRUCTURED MACROS (Continued)
-
- F. Repetition for a count
-
- Enter with CX set to the maximum number of times to repeat.
-
- XFOR NOZERO, LONG
- ; If NOZERO is blank, skip the body
- ; of the loop if CX starts as zero.
- ; If it exists, always repeat at
- ; least once.
- body
- XDEC CONDITION-3
- ; End of loop
-
-
- The value of NOZERO doesn't matter. For documentation, you
- might consider using nozero.
-
- LONG is only useful if NOZERO is blank. The three useful
- configurations of the FOR line are:
- FOR
- FOR nozero
- FOR , long
-
- CONDITION-3 can be blank for an unconditional loop or E, NZ,
- NE or Z for a conditional loop. See Section II-D for more
- information on CONDITION-3.
-
- If NOZERO is blank, XFOR contains a forward jump. If it is
- not blank, XFOR does not contain a forward jump.
-
- XFOR and XDEC form an enclosing block. XNEXT does not
- change the number of repetitions. If you want to bypass part of
- the processing for this repetition but keep on counting, enclose
- body with XBEGIN and XEND and then use XEXIT.
-
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 12
-
-
- STRUCTURED MACROS (Continued)
-
- G. WHILE
-
- XWHILE VAR1, CONDITION, VAR2, LONG
- ; Terminate loop if CONDITION-1
- body
- XENDLP ; End this pass through the loop
-
-
- If you want to initialize CONDITION-1 before entering and
- set it in body for the next pass through the loop, replace the
- XWHILE line with
- XWHILEC CONDITION-1, LONG
- ; Terminate loop if CONDTION-1
-
- XEXIT and XEXITC include forward jumps.
-
- XWHILE or XWHILEC and XENDLP form an enclosing block.
-
- H. REPEAT UNTIL
-
- XREPEAT ; Start of loop
- body
- XUNTIL VAR1, CONDITION, VAR2
- ; End this pass through the loop
-
- If you want to set CONDITION-1 in body, replace the XUNTIL
- line with
- XUNTILC CONDITION-1 ; End this pass through the loop
-
- XREPEAT and XUNTIL or XUNTILC form an enclosing block.
- XNEXT does not test CONDITION-1. If you want to bypass part of
- the processing for this repetition but still test, enclose body
- with XBEGIN and XEND and then use XEXIT.
-
- I. REPEAT FOREVER
-
- XLOOP
- body
- XENDLP
-
- body should include some form of XEXIT.
-
- XLOOP and XENDLP form an enclosing block.
-
- NOTE: XLOOP is a synonym for XREPEAT.
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 13
-
-
-
- VI. OTHER MACROS
-
- A. Multiple PUSH and POP
-
- PUSH_REGISTER <REGISTER LIST> pushes the list of registers
- contained in REGISTER LIST on the program stack and saves what it
- has done for POP_REGISTER.
-
- POP_REGISTER pops the registers saved by PUSH_REGISTER in
- the proper order.
-
- PUSHM <LIST> pushes the registers and memory locations
- contained in LIST on the program stack in the same order as LIST.
-
- POPM <LIST> pops the registers and memory locations
- contained in LIST from the program stack in the same order as
- LIST. If it is used with PUSHM, the two LIST's should be in
- reversed order.
-
- The angle brackets in PUSH_REGISTER, PUSHM and POPM are
- required.
-
- B. Show the state of the Zero Flag in AL
-
- GETZ sets AL to TRUE if the Zero Flag is set and to FALSE if
- it is not set.
-
- GETNZ sets AL to TRUE if the Zero Flag is not set and to
- FALSE if it is set.
-
-
- C. NOTZ - Toggle the Zero Flag
-
- D. Call procedures which use a string whose OFFSET is in either
- BX or DX
-
- CALLSTR ROUTINE, STRING
- where
- ROUTINE is the name of the procedure to call.
- STRING is the name of a string whose OFFSET should go
- into register DX.
-
- GETCALL ROUTINE, STRING
- where
- ROUTINE is the name of the procedure to call.
- STRING is the name of a string whose OFFSET should go
- into register BX.
-
-
-
-
-
-
- Documentation for MACROS.MLB Page 14
-
-
- OTHER MACROS (Continued)
-
-
- E. Call a procedure which uses a File Control Block
-
- FCBCALL ROUTINE, FCB, ERRORRTN
- where
- ROUTINE is the name of the procedure to call. It
- should set the Zero Flag if there is an error.
- FCB is the name of the File Control Block.
- ERRORRTN is the optional name of an error procedure
- which the program will call if the Zero Flag is set.
-
-